import * as fs from 'fs';
import * as path from 'path';
import * as vscode from 'vscode';
// @ts-ignore
import madge from 'madge';

interface SymbolInfo {
  name: string;
  kind: string;
  file: string;
  start: number;
  end: number;
  doc?: string;
}

interface ProjectIndex {
  files: string[];
  symbols: SymbolInfo[];
  dependencies: Record<string, string[]>;
  readmeSummary: string;
}

// 读取 README 并做摘要
function getReadmeSummary(root: string, maxLines = 30): string {
  const readmePath = path.join(root, 'README.md');
  if (fs.existsSync(readmePath)) {
    return fs.readFileSync(readmePath, 'utf-8').split('\n').slice(0, maxLines).join('\n');
  }
  return '';
}

// 递归扁平化 VSCode 符号树
function flattenSymbols(symbols: vscode.DocumentSymbol[], file: string, result: SymbolInfo[] = []): SymbolInfo[] {
  for (const sym of symbols) {
    result.push({
      name: sym.name,
      kind: sym.kind.toString(),
      file,
      start: sym.range.start.line + 1,
      end: sym.range.end.line + 1,
      doc: sym.detail
    });
    if (sym.children && sym.children.length > 0) {
      flattenSymbols(sym.children, file, result);
    }
  }
  return result;
}

// 用 madge 生成依赖关系
async function extractDependencies(entry: string) {
  const res = await madge(entry);
  return res.obj();
}

// 汇聚为全局索引对象并写入缓存文件，支持进度回调
export async function buildProjectIndex(
  root: string,
  progress?: vscode.Progress<{ message?: string; increment?: number }>,
) {

  // 查找所有代码文件，排除无关目录和文件
  const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
  if (!workspaceFolder) {
    throw new Error('No workspace folder is open.');
  }
  const pattern = new vscode.RelativePattern(root, '**/*.{ts,js,tsx,jsx,py,vue,java,kt,go,cs}');
  const uris = await vscode.workspace.findFiles(pattern);
  const projectRoot = path.resolve(root);
  const allFiles = uris.map(u => u.fsPath);
  console.log('所有匹配到的文件:', allFiles);
  const EXCLUDE_KEYWORDS = [
    'node_modules', 'dist', 'build', 'out', '.git', '.vscode', 'test', 'tests', 'coverage',
    'public', 'static', 'resources', 'assets', 'bin', 'lib', 'target', 'release', 'debug',
    'docs', 'doc', 'examples', 'samples', '__tests__', 'spec', 'specs'
  ];
  const files = allFiles.filter(f => {
    const rel = path.relative(projectRoot, f);
    const parts = rel.split(path.sep);
    return !EXCLUDE_KEYWORDS.includes(parts[0]);
  });
  const excludedFiles = allFiles.filter(f => {
    const rel = path.relative(projectRoot, f);
    const parts = rel.split(path.sep);
    return EXCLUDE_KEYWORDS.includes(parts[0]);
  });
  console.log('被排除的文件:', excludedFiles);
  // 只显示可被索引的文件数
  console.log('可被索引的文件数:', files.length);
  let symbols: SymbolInfo[] = [];
  for (let i = 0; i < uris.length; i++) {
    const uri = uris[i];
    const docSymbols = await vscode.commands.executeCommand<vscode.DocumentSymbol[]>(
      'vscode.executeDocumentSymbolProvider', uri
    );
    if (docSymbols) {
      symbols = symbols.concat(flattenSymbols(docSymbols, uri.fsPath));
    }
    if (progress && i % 10 === 0) {
      progress.report({
        increment: (i / uris.length) * 100,
        message: `已处理 ${i + 1}/${uris.length} 个文件`
      });
    }
  }
  const dependencies = await extractDependencies(root);
  const readmeSummary = getReadmeSummary(root);
  const index: ProjectIndex = {
    files,
    symbols,
    dependencies,
    readmeSummary
  };
  // 新增：将索引文件写入 .cursor-indexes/项目名.json
  const projectName = path.basename(root);
  const indexDir = path.join(root, '.cursor-indexes');
  if (!fs.existsSync(indexDir)) {
    fs.mkdirSync(indexDir);
  }
  const indexFile = path.join(indexDir, `${projectName}.json`);
  fs.writeFileSync(indexFile, JSON.stringify(index, null, 2), 'utf-8');
  console.log('项目索引已生成:', indexFile);
  // 只打印可被索引的文件数
  // console.log('索引内容:', JSON.stringify(index, null, 2));
  return index;
}
